#include <bits/stdc++.h>
using namespace std;
const int N = 1000000 + 10;
int vis[N];
int read(){
    char ch; int sum = 0,flag = 1;
    ch = getchar();
    while(ch < '0' || ch > '9'){if(ch == '-') flag = -flag; ch = getchar();}
    while(ch >= '0' && ch <= '9'){sum = sum * 10 + ch - '0'; ch = getchar();}
    return flag * sum;
}
struct node{
    int lft,rgt;	
}rang[N];
int n,m,T,V,L,ans;
int d[N],v[N],a[N],p[N];
int l[N],r[N];
int top;
bool cmp(node a,node b){
    if(a.rgt == b.rgt) return a.lft < b.lft;
    return a.rgt < b.rgt;	
}
int main(){
	freopen("detect.in","r",stdin);
	freopen("detect.out","w",stdout);
    T = read();
    while(T--){
        memset(l,0,sizeof(l));
        memset(r,0,sizeof(r));
        memset(vis,0,sizeof(vis));
        ans = 0;
        top = 0;
        n = read(); m = read(); L = read(); V = read(); 
        for(int i = 1; i <= n; i++){
            d[i] = read(); v[i] = read(); a[i] = read();
        }
        for(int i = 1; i <= m; i++){
            p[i] = read();
            l[p[i]] = i;
            r[p[i]] = i;
            vis[p[i]] = 1;
        }
        for(int i = 1; i <= L; i++){
            if(l[i] > 0) continue;
            l[i] = l[i - 1];
        }
        for(int i = L; i >= 0; i--){
            if(r[i] > 0) continue;
            r[i] = r[i + 1];
        }
        for(int i = 1; i <= L; i++) vis[i] += vis[i - 1];
        for(int i = 1; i <= n; i++){
            if(a[i] == 0){
                if(v[i] > V) {
						if(vis[L] - vis[d[i] - 1] > 0){
                        ans++;
                        rang[++top].lft = r[d[i]];
                        rang[top].rgt = l[L];
					}
                }
            }
            else if(a[i] > 0){
                if(v[i] > V){
                   if(vis[L] - vis[d[i] - 1] > 0){
					   ans++;
                       rang[++top].lft = r[d[i]];
                       rang[top].rgt = l[L];
			       }
                }
                else{
                    double x = (((V * V - v[i] * v[i]) * 1.0) / (2.0 * a[i] * 1.0)) + 0.00000001;
                    int loc = ceil(x) + d[i];
                    if((V * V - v[i] * v[i]) % (2 * a[i]) == 0) loc = d[i] + (V * V - v[i] * v[i]) / (2 * a[i]) + 1;
                    if(loc <= L && vis[L] - vis[loc - 1] > 0){
                        ans++;
                        rang[++top].lft = r[loc];
                        rang[top].rgt = l[L];
                    } 
                }       
            }
            else if(a[i] < 0){
                if(v[i] <= V) continue;
                double x = ((v[i] * v[i] - V * V) * 1.0) / (2.0 * (-a[i]) * 1.0) + 0.00000001;
                int loc = floor(x) + d[i];
                if((v[i] * v[i] - V * V) % (2 * (-a[i])) == 0) loc = d[i] + (v[i] * v[i] - V * V) / (2 * (-a[i])) - 1;
                loc = min(loc,L);
                if(vis[loc] - vis[d[i] - 1] > 0){
					ans++;
                    rang[++top].lft = r[d[i]];
                    rang[top].rgt = l[loc];
			    }
            }
        }
        printf("%d ",ans);
        sort(rang + 1,rang + top + 1,cmp);
        int lst = -1,aans = 0;
        for(int i = 1; i <= top; i++){
		    if(rang[i].lft <= lst) continue;
		    aans++;
		    lst = rang[i].rgt;
		}
		printf("%d\n",m - aans);
    }
    return 0;
}
